package cn.virens.mybatis.mapper.example.base;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import cn.virens.common.exception.APIException;
import cn.virens.mybatis.mapper.example.ExampleCriteria;
import cn.virens.mybatis.mapper.example.ExampleHaving;
import cn.virens.mybatis.mapper.example.ExampleJoin;

@SuppressWarnings("serial")
public abstract class AbstractExample implements Serializable {
	protected final List<ExampleCriteria> criteriaList = new ArrayList<>();
	protected final List<ExampleHaving> havingList = new ArrayList<>();
	protected final List<ExampleJoin> joinList = new ArrayList<>();
	protected final Set<String> selectColumns = new HashSet<>();

	// 排序字段
	protected String orderByClause;

	// 分组字段
	protected String groupByClause;

	// 分页字段
	protected String limitByClause;

	public String getOrderByClause() {
		return orderByClause;
	}

	public void setOrderByClause(String orderByClause) {
		this.orderByClause = orderByClause;
	}

	public String getGroupByClause() {
		return groupByClause;
	}

	public void setGroupByClause(String groupByClause) {
		this.groupByClause = groupByClause;
	}

	public String getLimitByClause() {
		return limitByClause;
	}

	public void setLimitByClause(String limitByClause) {
		this.limitByClause = limitByClause;
	}

	public void setLimitByClause(Integer limit) {
		this.setLimitByClause(String.valueOf(limit));
	}

	public void setLimitByClause(Integer limit, Integer offset) {
		this.setLimitByClause(offset + "," + limit);
	}

	public List<ExampleJoin> getJoinList() throws APIException {
		return joinList.stream().filter(a -> {
			return a != null && a.isVerify();
		}).collect(Collectors.toList());
	}

	public List<ExampleHaving> getHavingList() throws APIException {
		return havingList.stream().filter(a -> {
			return a != null && a.isVerify();
		}).collect(Collectors.toList());
	}

	public List<ExampleCriteria> getCriteriaList() throws APIException {
		return criteriaList.stream().filter(a -> {
			return a != null && a.isVerify();
		}).collect(Collectors.toList());
	}

	public Set<String> getSelectColumns() {
		return selectColumns;
	}

	public void addSelectColumns(String... strs) {
		this.selectColumns.addAll(Arrays.asList(strs));
	}

	public ExampleCriteria addCriteria(ExampleCriteria criteria) {
		if (criteriaList.add(criteria)) {
			return criteria;
		} else {
			return null;
		}
	}

	public ExampleHaving addHaving(ExampleHaving having) {
		if (havingList.add(having)) {
			return having;
		} else {
			return null;
		}
	}

	public ExampleJoin addJoin(ExampleJoin join) {
		if (joinList.add(join)) {
			return join;
		} else {
			return null;
		}
	}

}
